package net.maku.kyy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.constant.MessageConstant;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.security.config.PasswordConfig;
import net.maku.framework.security.crypto.Sm2Util;
import net.maku.framework.security.utils.ThreadLocalUtil;
import net.maku.kyy.constant.KyyConstant;
import net.maku.kyy.constant.KyyRedisKeyConstant;
import net.maku.kyy.convert.KyyUserConvert;
import net.maku.kyy.entity.KyyUserEntity;
import net.maku.kyy.query.KyyUserQuery;
import net.maku.kyy.utils.GetUserMessageUtil;
import net.maku.kyy.vo.CommentStatusTimeVO;
import net.maku.kyy.vo.KyyUserInfoVO;
import net.maku.kyy.vo.KyyUserVO;
import net.maku.kyy.dao.KyyUserDao;
import net.maku.kyy.service.KyyUserService;
import com.fhs.trans.service.impl.TransService;
import net.maku.framework.common.utils.ExcelUtils;
import net.maku.kyy.vo.KyyUserExcelVO;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Key;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 前台用户表
 *
 * @author MAKU babamu@126.com
 * <a href="https://maku.net">MAKU</a>
 */
@Service
@AllArgsConstructor
public class KyyUserServiceImpl extends BaseServiceImpl<KyyUserDao, KyyUserEntity> implements KyyUserService {
    private final TransService transService;
    @Autowired
    private KyyUserDao kyyUserDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public PageResult<KyyUserVO> page(KyyUserQuery query) {
        // 获取所有用户数据，包括已删除的
        IPage<KyyUserEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        // 获取用户的发言权限
        List<KyyUserVO> kyyUserVOList = KyyUserConvert.INSTANCE.convertList(page.getRecords());
        getUserCommentPermission(kyyUserVOList);

        // 根据评论权限过滤数据
        if (query.getCommentPermission() != null) {
            List<KyyUserVO> kyyUserVOListExitCom = new ArrayList<>();
            for (KyyUserVO kyyUserVO : kyyUserVOList) {
                if (query.getCommentPermission().longValue() == kyyUserVO.getCommentPermission()) {
                    kyyUserVOListExitCom.add(kyyUserVO);
                }
            }
            return new PageResult<>(kyyUserVOListExitCom, kyyUserVOListExitCom.size());
        }

        // 返回所有用户数据，包括已删除的
        return new PageResult<>(kyyUserVOList, page.getTotal());
    }



    /**
     * 获取用户的发言权限
     * @param kyyUserVOList
     */
    private void getUserCommentPermission(List<KyyUserVO> kyyUserVOList) {
        for (KyyUserVO kyyUserVO : kyyUserVOList) {
            String key= KyyRedisKeyConstant.KYY_USER+kyyUserVO.getId()+KyyRedisKeyConstant.REPLAY_BAN;
            //获取发言权限和封禁理由
            //发言权限：0：禁用 1:正常
            if (redisTemplate.hasKey(key)){
                //禁用状态和封禁理由
                kyyUserVO.setCommentPermission(Constant.COMMENT_BAN);
                String commentBanReason= (String) redisTemplate.opsForValue().get(key);
                kyyUserVO.setCommentBanReason(commentBanReason);
                kyyUserVO.setSilenceEndTime(String.valueOf(redisTemplate.getExpire(key, TimeUnit.SECONDS)));
            }  else {
                kyyUserVO.setCommentPermission(Constant.COMMENT_NORMAL);
            }
        }
    }


//    private LambdaQueryWrapper<KyyUserEntity> getWrapper(KyyUserQuery query){
//        LambdaQueryWrapper<KyyUserEntity> wrapper = Wrappers.lambdaQuery();
//        if (query.getNickName() != null && !query.getNickName().isEmpty()) {
//            wrapper.like(KyyUserEntity::getNickName, query.getNickName());
//        }
//        if (query.getMobile()!=null&&!query.getMobile().isEmpty()){
//            wrapper.like(KyyUserEntity::getMobile, query.getMobile());
//        }
//        if (query.getAccount()!=null&&!query.getAccount().isEmpty()){
//            wrapper.like(KyyUserEntity::getAccount, query.getAccount());
//        }
//        if (query.getBirthday()!=null){
//            wrapper.eq(KyyUserEntity::getBirthday, query.getBirthday());
//        }
//        if (query.getEmail() != null && !query.getEmail().isEmpty()) {
//            wrapper.like(KyyUserEntity::getEmail, query.getEmail());
//        }
//        if (query.getGender() != null) {
//            wrapper.eq(KyyUserEntity::getGender, query.getGender());
//        }
//        if (query.getWechatId()!=null&&!query.getWechatId().isEmpty()){
//            wrapper.like(KyyUserEntity::getWechatId, query.getWechatId());
//        }
//        if (query.getStatus()!=null){
//            wrapper.like(KyyUserEntity::getStatus, query.getStatus());
//        }
//        if (query.getForumPermission()!=null){
//            wrapper.eq(KyyUserEntity::getForumPermission, query.getForumPermission());
//        }
//        if (query.getLastLoginTime()!=null&&query.getLastLoginTime().length>0){
//            //时间范围查询
//            wrapper.ge(KyyUserEntity::getLastLoginTime, query.getLastLoginTime()[0]).le(KyyUserEntity::getLastLoginTime, query.getLastLoginTime()[1]);
//        }
//        if (query.getDeleted()!=null){
//            wrapper.eq(KyyUserEntity::getDeleted, query.getDeleted());
//        }
//        return wrapper;
//    }



    private LambdaQueryWrapper<KyyUserEntity> getWrapper(KyyUserQuery query) {
        LambdaQueryWrapper<KyyUserEntity> wrapper = Wrappers.lambdaQuery();
        if (query.getNickName() != null && !query.getNickName().isEmpty()) {
            wrapper.like(KyyUserEntity::getNickName, query.getNickName());
        }
        if (query.getMobile() != null && !query.getMobile().isEmpty()) {
            wrapper.like(KyyUserEntity::getMobile, query.getMobile());
        }
        if (query.getAccount() != null && !query.getAccount().isEmpty()) {
            wrapper.like(KyyUserEntity::getAccount, query.getAccount());
        }
        if (query.getBirthday() != null) {
            wrapper.eq(KyyUserEntity::getBirthday, query.getBirthday());
        }
        if (query.getEmail() != null && !query.getEmail().isEmpty()) {
            wrapper.like(KyyUserEntity::getEmail, query.getEmail());
        }
        if (query.getGender() != null) {
            wrapper.eq(KyyUserEntity::getGender, query.getGender());
        }
        if (query.getWechatId() != null && !query.getWechatId().isEmpty()) {
            wrapper.like(KyyUserEntity::getWechatId, query.getWechatId());
        }
        if (query.getStatus() != null) {
            wrapper.like(KyyUserEntity::getStatus, query.getStatus());
        }
        if (query.getForumPermission() != null) {
            wrapper.eq(KyyUserEntity::getForumPermission, query.getForumPermission());
        }
        if (query.getLastLoginTime() != null && query.getLastLoginTime().length > 0) {
            // 时间范围查询
            wrapper.ge(KyyUserEntity::getLastLoginTime, query.getLastLoginTime()[0])
                    .le(KyyUserEntity::getLastLoginTime, query.getLastLoginTime()[1]);
        }
        if (query.getDeleted() != null) {
            wrapper.eq(KyyUserEntity::getDeleted, query.getDeleted());
        }
        return wrapper;
    }


    @Override
    public KyyUserVO get(Long id) {
        KyyUserEntity entity = baseMapper.selectById(id);
        KyyUserVO vo = KyyUserConvert.INSTANCE.convert(entity);
        List<KyyUserVO> kyyUserVOList =new ArrayList<>();
        kyyUserVOList.add(vo);
        getUserCommentPermission(kyyUserVOList);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(KyyUserVO vo) {
        KyyUserEntity entity = KyyUserConvert.INSTANCE.convert(vo);
        entity.setPassword(Sm2Util.encrypt(vo.getPassword()));
        entity.setAccount(GetUserMessageUtil.RandomAccount());
        baseMapper.insert(entity);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(KyyUserVO vo) {
        KyyUserEntity entity = KyyUserConvert.INSTANCE.convert(vo);

        updateById(entity);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
//        removeByIds(idList);
        //实现化学删除，改变删除状态
        kyyUserDao.updateDelStuatsByIds(idList);
    }



    @Override
    public void export() {
    List<KyyUserExcelVO> excelList = KyyUserConvert.INSTANCE.convertExcelList(list());
        transService.transBatch(excelList);
        ExcelUtils.excelExport(KyyUserExcelVO.class, "前台用户表", null, excelList);
    }

    /**
     * 获取用户信息
     * @return
     */
    @Override
    public KyyUserInfoVO getUserInfo() {
        Map map= ThreadLocalUtil.get();
        if (map.size()==0){
            throw new ServerException(MessageConstant.PLEASE_LOGIN);
        }
        Long userId = (Long) map.get(KyyConstant.KYY_USER_ID);
        //根据id查询
        KyyUserEntity kyyUserEntity = kyyUserDao.selectById(userId);
        KyyUserInfoVO kyyUserInfoVO = BeanUtil.copyProperties(kyyUserEntity, KyyUserInfoVO.class);
        kyyUserInfoVO.setAvatarUrl(kyyUserEntity.getAvatar());
        kyyUserInfoVO.setName(kyyUserEntity.getNickName());
        return kyyUserInfoVO;
    }


    /**
     * 修改用户状态
     * @param userId
     */
    @Override
    public void updateUserStatus(Long userId) throws ServerException {
        KyyUserEntity kyyUserEntity = kyyUserDao.selectById(userId);
        if (kyyUserEntity == null) {
            throw new ServerException(MessageConstant.USER_NOT_EXIST);
        }
        if(kyyUserEntity.getStatus()==Constant.USER_STATUS_DISABLE){
            //状态处于禁用，变为启用
            kyyUserEntity.setStatus(Constant.USER_STATUS_NORMAL);
            kyyUserDao.updateById(kyyUserEntity);
        }else {
            //状态处于启用，变为禁用
            kyyUserEntity.setStatus(Constant.USER_STATUS_DISABLE);
            kyyUserDao.updateById(kyyUserEntity);
        }
    }

    @Override
    public void updateForumStatus(Long userId) {
        KyyUserEntity kyyUserEntity = kyyUserDao.selectById(userId);
        if (kyyUserEntity == null) {
            throw new ServerException(MessageConstant.USER_NOT_EXIST);
        }
        if (kyyUserEntity.getForumPermission()==Constant.FORUM_PUBLISH_BAN_LONG){
            //状态处于禁用，变为正常
            kyyUserEntity.setForumPermission(Constant.FORUM_PUBLISH_NORMAL_LONG);
            kyyUserDao.updateById(kyyUserEntity);
        }else{
            //状态处于正常，变为禁用
            kyyUserEntity.setForumPermission(Constant.FORUM_PUBLISH_BAN_LONG);
            kyyUserDao.updateById(kyyUserEntity);
        }
    }

    /**
     * 修改评论状态
     * @param userId
     */
    @Override
    public void updateCommentStatus(Long userId) {
//        GetUserMessageUtil.getUserId();
        KyyUserEntity kyyUserEntity = kyyUserDao.selectById(userId);
        if (kyyUserEntity == null) {
            throw new ServerException(MessageConstant.USER_NOT_EXIST);
        }
        //key=kyy_user+userId+replay_ban+封禁开始时间
        String key=KyyRedisKeyConstant.KYY_USER+userId+KyyRedisKeyConstant.REPLAY_BAN;
        if (!redisTemplate.hasKey(key)){
            //不存在，进行封禁5min
            redisTemplate.opsForValue().set(key, Constant.ADMIN_BAN,5, TimeUnit.MINUTES);
        }else {
            //存在解封
            redisTemplate.delete(key);
        }
    }

    /**
     * 修改评论状态时间
     * @param commentStatusTimeVO
     */
    @Override
    public void updateCommentStatusTime(CommentStatusTimeVO commentStatusTimeVO) {
//        GetUserMessageUtil.getUserId();
        Long userId = commentStatusTimeVO.getUserId();
        KyyUserEntity kyyUserEntity = kyyUserDao.selectById(userId);
        if (kyyUserEntity == null) {
            throw new ServerException(MessageConstant.USER_NOT_EXIST);
        }
        String key=KyyRedisKeyConstant.KYY_USER+userId+KyyRedisKeyConstant.REPLAY_BAN;
        if (commentStatusTimeVO.getUnit().equals("min")){
            //key=kyy_user+userId+replay_ban
            redisTemplate.opsForValue().set(key,commentStatusTimeVO.getReason(),commentStatusTimeVO.getTime(), TimeUnit.MINUTES);
        }else if (commentStatusTimeVO.getUnit().equals("hour")){
            //key=kyy_user+userId+replay_ban
            redisTemplate.opsForValue().set(key,commentStatusTimeVO.getReason(),commentStatusTimeVO.getTime(), TimeUnit.HOURS);
        }else if (commentStatusTimeVO.getUnit().equals("day")){
            redisTemplate.opsForValue().set(key,commentStatusTimeVO.getReason(),commentStatusTimeVO.getTime(), TimeUnit.DAYS);
        }else if (commentStatusTimeVO.getUnit().equals("permanent")){
            redisTemplate.opsForValue().set(key,commentStatusTimeVO.getReason());
        }else{
            //解封
            redisTemplate.delete(key);
        }
    }

    /**
     * 获取禁用所剩事件
     * @param userId
     * @return
     */
    @Override
    public Long getSilenceRemainingTime(Long userId) {
        String key=KyyRedisKeyConstant.KYY_USER+userId+KyyRedisKeyConstant.REPLAY_BAN;
        Long time = redisTemplate.getExpire(key, TimeUnit.SECONDS);
        return time;
    }
}